package com.dkts.oil.service.impl;

import com.dkts.oil.config.OilConfig;
import com.dkts.oil.converter.GeometryConverter;
import com.dkts.oil.converter.WriterToFile;
import com.dkts.oil.util.GeoAreaUtil;
import com.dkts.oil.web.vo.request.SiteSelectionRequest;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import com.dkts.oil.router.param.PathInfo;

import java.util.ArrayList;
import java.util.List;

public class OilAddressV2Helper {


    /**
     * 获取油库地址 规划区域
     * @param request
     * @param config
     * @return
     * @throws Exception
     */
    public static Geometry getArearGeometry(SiteSelectionRequest request, OilConfig config) throws Exception{
        WriterToFile.writerFileGeoJson(config.getTempDir()+"/机场.geojson",request.pointAreaPolygon);
        WriterToFile.writerFileGeoJson(config.getTempDir()+"/中心点.geojson",request.point);
        if (request.getCustomArea() != null){
            for (int i=0;i<request.getCustomArea().size();i++){
                WriterToFile.writerFileGeoJson(config.getTempDir()+"/自定义-"+i+".geojson",request.getCustomArea().get(i).getCustomAreaPolygon());
            }
        }

        //创建可以规划的区域
        Geometry planGeometry= GeometryConverter.getBuff(request.getPoint(),request.getRangePointDistance());
        request.setPointAreaPolygon(planGeometry);
        WriterToFile.writerFileGeoJson(config.getTempDir()+"/规划区域ALL.geojson",planGeometry);
        //相交取反
        if (request.getConstraintConfig() != null && request.getConstraintConfig().getMinDistanceToAirportCenter() != null){
            Geometry bufferGeometry=GeometryConverter.getBuff(request.getPoint(),request.getConstraintConfig().getMinDistanceToAirportCenter());
            WriterToFile.writerFileGeoJson(config.getTempDir()+"/与机场中心点最小距离.geojson",bufferGeometry);

            //相交取反
            planGeometry= GeometryConverter.difference(planGeometry,bufferGeometry);
            request.setPointAreaPolygon(planGeometry);
            WriterToFile.writerFileGeoJson(config.getTempDir()+"/规划区域取反.geojson",planGeometry);
        }
        Double d= GeoAreaUtil.signedArea(request.getPointAreaPolygon().getCoordinates());
        System.out.println("规划区域面积："+  String.format("%.2f", d));
        if (request.getAreaConfig().getTotalArea() > d){
            throw new RuntimeException("规划区域面积不足");
        }
        return request.getPointAreaPolygon();
    }
    public static double calculateBearing(SiteSelectionRequest.AddressPoint from, Point to) {
        double lon1 = Math.toRadians(from.getLon());
        double lat1 = Math.toRadians(from.getLat());
        double lon2 = Math.toRadians(to.getX());
        double lat2 = Math.toRadians(to.getY());

        double dLon = lon2 - lon1;
        double y = Math.sin(dLon) * Math.cos(lat2);
        double x = Math.cos(lat1) * Math.sin(lat2)
                - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon);
        double bearing = Math.toDegrees(Math.atan2(y, x));

        return (bearing + 360) % 360;
    }

    public static String getDirectionName(double bearing) {
        String[] directions = {"北", "东北", "东", "东南", "南", "西南", "西", "西北"};
        int index = (int) Math.round(((bearing % 360) / 45)) % 8;
        return directions[index];
    }
    /**
     * 将 instructions 分段汇总成路段摘要列表
     * @param instructions 路径指令列表
     * @return 路段汇总列表
     */
    public static List<PathInfo.RoadSegmentSummary> summarizeInstructions(List<PathInfo.Instructions> instructions) {
        List<PathInfo.RoadSegmentSummary> summaries = new ArrayList<>();
        if (instructions == null || instructions.isEmpty()) return summaries;

        String startName = "起点";
        String endName = null;
        double totalDistance = 0;
        long totalTime = 0;
        int index = 1;
        List<String> actions = new ArrayList<>();

        for (int i = 0; i < instructions.size(); i++) {
            PathInfo.Instructions ins = instructions.get(i);

            // 动作加入动作数组
            actions.add(ins.getText());

            totalDistance += ins.getDistance();
            totalTime += ins.getTime();

            // endName 判断
            String tmpEndName = null;
            if (ins.getStreetName() != null && !ins.getStreetName().isEmpty()) {
                tmpEndName = ins.getStreetName();
            }

            // 是否到达分段点
            boolean isSegmentEnd = false;
            if (tmpEndName != null) {
                endName = tmpEndName;
                isSegmentEnd = true;
            }

            // 最后一条强制分段
            if (i == instructions.size() - 1) {
                if ("到达终点".equals(ins.getText())) {
                    endName = "终点";
                } else if (endName == null) {
                    endName = startName;
                }
                isSegmentEnd = true;
            }

            if (isSegmentEnd) {
                PathInfo.RoadSegmentSummary summary = new PathInfo.RoadSegmentSummary();
                summary.setCode("A" + index);
                summary.setRoadName(startName + " → " + endName);
                summary.setDistanceKm(roundKm(totalDistance));
                summary.setDurationMin((int) Math.round(totalTime / 60000.0));
                summary.setActions(new ArrayList<>());

                summaries.add(summary);

                // 重置
                startName = endName;
                totalDistance = 0;
                totalTime = 0;
                actions.clear();
                index++;
            }
        }

        return summaries;
    }


    // 保留一位小数
    private static double roundKm(double meter) {
        return Math.round(meter / 100.0) / 10.0;
    }


}
